home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / language / harvest.cpt / Harvest C / Tcl 6.2 / tclAssem.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-12  |  5.7 KB  |  211 lines

  1. #ifdef macintosh
  2. #    pragma segment tclAssem
  3. #endif
  4.  
  5. /* 
  6.  * tclAssem.c --
  7.  *
  8.  *    This file contains procedures to help assemble Tcl commands
  9.  *    from an input source  where commands may arrive in pieces, e.g.
  10.  *    several lines of type-in corresponding to one command.
  11.  *
  12.  * Copyright 1990-1991 Regents of the University of California
  13.  * Permission to use, copy, modify, and distribute this
  14.  * software and its documentation for any purpose and without
  15.  * fee is hereby granted, provided that the above copyright
  16.  * notice appear in all copies.  The University of California
  17.  * makes no representations about the suitability of this
  18.  * software for any purpose.  It is provided "as is" without
  19.  * express or implied warranty.
  20.  */
  21.  
  22. #ifndef lint
  23. static char rcsid[] = "$Header: /sprite/src/lib/tcl/RCS/tclAssem.c,v 1.8 91/09/23 11:22:22 ouster Exp $ SPRITE (Berkeley)";
  24. #endif /* not lint */
  25.  
  26. #include "tclInt.h"
  27.  
  28. /*
  29.  * The structure below is the internal representation for a command
  30.  * buffer, which is used to hold a piece of a command until a full
  31.  * command is available.  When a full command is available, it will
  32.  * be returned to the user, but it will also be retained in the buffer
  33.  * until the NEXT call to Tcl_AssembleCmd, at which point it will be
  34.  * removed.
  35.  */
  36.  
  37. typedef struct {
  38.     char *buffer;        /* Storage for command being assembled.
  39.                  * Malloc-ed, and grows as needed. */
  40.     int bufSize;        /* Total number of bytes in buffer. */
  41.     int bytesUsed;        /* Number of bytes in buffer currently
  42.                  * occupied (0 means there is not a
  43.                  * buffered incomplete command). */
  44. } CmdBuf;
  45.  
  46. /*
  47.  * Default amount of space to allocate in command buffer:
  48.  */
  49.  
  50. #define CMD_BUF_SIZE 100
  51.  
  52. /*
  53.  *----------------------------------------------------------------------
  54.  *
  55.  * Tcl_CreateCmdBuf --
  56.  *
  57.  *    Allocate and initialize a command buffer.
  58.  *
  59.  * Results:
  60.  *    The return value is a token that may be passed to
  61.  *    Tcl_AssembleCmd and Tcl_DeleteCmdBuf.
  62.  *
  63.  * Side effects:
  64.  *    Memory is allocated.
  65.  *
  66.  *----------------------------------------------------------------------
  67.  */
  68.  
  69. Tcl_CmdBuf
  70. Tcl_CreateCmdBuf()
  71. {
  72.     register CmdBuf *cbPtr;
  73.  
  74.     cbPtr = (CmdBuf *) ckalloc(sizeof(CmdBuf));
  75.     cbPtr->buffer = (char *) ckalloc(CMD_BUF_SIZE);
  76.     cbPtr->bufSize = CMD_BUF_SIZE;
  77.     cbPtr->bytesUsed = 0;
  78.     return (Tcl_CmdBuf) cbPtr;
  79. }
  80.  
  81. /*
  82.  *----------------------------------------------------------------------
  83.  *
  84.  * Tcl_DeleteCmdBuf --
  85.  *
  86.  *    Release all of the resources associated with a command buffer.
  87.  *    The caller should never again use buffer again.
  88.  *
  89.  * Results:
  90.  *    None.
  91.  *
  92.  * Side effects:
  93.  *    Memory is released.
  94.  *
  95.  *----------------------------------------------------------------------
  96.  */
  97.  
  98. void
  99. Tcl_DeleteCmdBuf(buffer)
  100.     Tcl_CmdBuf buffer;        /* Token for command buffer (return value
  101.                  * from previous call to Tcl_CreateCmdBuf). */
  102. {
  103.     register CmdBuf *cbPtr = (CmdBuf *) buffer;
  104.  
  105.     ckfree(cbPtr->buffer);
  106.     ckfree((char *) cbPtr);
  107. }
  108.  
  109. /*
  110.  *----------------------------------------------------------------------
  111.  *
  112.  * Tcl_AssembleCmd --
  113.  *
  114.  *    This is a utility procedure to assist in situations where
  115.  *    commands may be read piece-meal from some input source.  Given
  116.  *    some input text, it adds the text to an input buffer and returns
  117.  *    whole commands when they are ready.
  118.  *
  119.  * Results:
  120.  *    If the addition of string to any currently-buffered information
  121.  *    results in one or more complete Tcl commands, then the return value
  122.  *    is a pointer to the complete command(s).  The command value will
  123.  *    only be valid until the next call to this procedure with the
  124.  *    same buffer.  If the addition of string leaves an incomplete
  125.  *    command at the end of the buffer, then NULL is returned.
  126.  *
  127.  * Side effects:
  128.  *    If string leaves a command incomplete, the partial command
  129.  *    information is buffered for use in later calls to this procedure.
  130.  *    Once a command has been returned, that command is deleted from
  131.  *    the buffer on the next call to this procedure.
  132.  *
  133.  *----------------------------------------------------------------------
  134.  */
  135.  
  136. char *
  137. Tcl_AssembleCmd(buffer, string)
  138.     Tcl_CmdBuf buffer;        /* Token for a command buffer previously
  139.                  * created by Tcl_CreateCmdBuf.  */
  140.     char *string;        /* Bytes to be appended to command stream.
  141.                  * Note:  if the string is zero length,
  142.                  * then whatever is buffered will be
  143.                  * considered to be a complete command
  144.                  * regardless of whether parentheses are
  145.                  * matched or not. */
  146. {
  147.     register CmdBuf *cbPtr = (CmdBuf *) buffer;
  148.     int length, totalLength;
  149.     register char *p;
  150.  
  151.     /*
  152.      * If an empty string is passed in, just pretend the current
  153.      * command is complete, whether it really is or not.
  154.      */
  155.  
  156.     length = strlen(string);
  157.     if (length == 0) {
  158.     cbPtr->bytesUsed = 0;
  159.     return cbPtr->buffer;
  160.     }
  161.  
  162.     /*
  163.      * Add the _new information to the buffer.  If the current buffer
  164.      * isn't large enough, grow it by at least a factor of two, or
  165.      * enough to hold the _new text.
  166.      */
  167.  
  168.     length = strlen(string);
  169.     totalLength = cbPtr->bytesUsed + length + 1;
  170.     if (totalLength > cbPtr->bufSize) {
  171.     unsigned int newSize;
  172.     char *newBuf;
  173.  
  174.     newSize = cbPtr->bufSize*2;
  175.     if (newSize < totalLength) {
  176.         newSize = totalLength;
  177.     }
  178.     newBuf = (char *) ckalloc(newSize);
  179.     strcpy(newBuf, cbPtr->buffer);
  180.     ckfree(cbPtr->buffer);
  181.     cbPtr->buffer = newBuf;
  182.     cbPtr->bufSize = newSize;
  183.     }
  184.     strcpy(cbPtr->buffer+cbPtr->bytesUsed, string);
  185.     cbPtr->bytesUsed += length;
  186.  
  187.     /*
  188.      * See if there is now a complete command in the buffer.
  189.      */
  190.  
  191.     p = cbPtr->buffer;
  192.     while (1) {
  193.     int gotNewLine = 0;
  194.  
  195.     while (isspace(*p)) {
  196.         if (*p == '\n') {
  197.         gotNewLine = 1;
  198.         }
  199.         p++;
  200.     }
  201.     if (*p == 0) {
  202.         if (gotNewLine) {
  203.         cbPtr->bytesUsed = 0;
  204.         return cbPtr->buffer;
  205.         }
  206.         return NULL;
  207.     }
  208.     p = TclWordEnd(p, 0);
  209.     }
  210. }
  211.